package physics;


import java.awt.event.ActionEvent;

import game.Game;
import globals.ObjectFactory;
import globals.ObjectType;
import physics.Collisions.Collision;
import physics.MovementControl.JumperMovementController;

import common.Math3D;


public class Avatar extends GameObject{

	double step = 0.05;
	double rotAngle = 0.05;
	double jumpStrength = 0.4;
	int carrots = 0;
	int lives = 5;
	int ticks = 0;
	int ticksPerRobotHit = 40;
	
	int ticksToAllowGrenade = 12;
	int ticksToAllowMissile = 24;
	int ticks_grenade = 0;
	int ticks_missile = 0;
	
	private int weapon = 1; //1 or 2
	
	public Avatar (){
		this.setMovementControler(new JumperMovementController(this));
		this.getMovementControler().setMovement(Math3D.scalePoint(this.getFace(), 0.2));
	}

	public void impact(Collision c)
	{
		GameObject bumpedInto;	
		if (c.getObj1().equals(this))
			bumpedInto= c.getObj2();
		else
			bumpedInto = c.getObj1();

		switch (c.getType()){
		case CARROT:
			if (bumpedInto.getName()!= null && bumpedInto.getName().equals("theOne")){
				Game.gameOver();
			}
			if ( ((Carrot)bumpedInto).canHit()){
				((Carrot)bumpedInto).setCanHit(false);
				carrots++;
				if (lives<5)
					lives++;
			}
			break;
		case PORTAL:
			getMovementControler().restoreLastPosition();
			if (Game.canEnterPortal(this )){
				PortalExit exit= ((PortalEntrance)bumpedInto).getExit();
				landOnPlanet(exit.getPlanet());
				this.getPosition().copy(exit.getPosition());
				Game.doneLevel();
			}
			break;
		case LAVAPLANET:
			lives--;
			jump();
			jump();
			jump();
			jump();
			setMoved(true);
			break;
		case KNIFE:
			if ( ((Knife)bumpedInto).canHit()){
				lives--;
				((Knife)bumpedInto).setCanHit(false);
			//setMoved(true);
			}	
			break;
			
		case GRENADE:
			if ( ((Grenade)bumpedInto).canHit()){
				if (!((Grenade)bumpedInto).disappearing){
					((Grenade)bumpedInto).explode();
				}
				((Grenade)bumpedInto).setCanHit(false);
				lives--;
				
			}
			break;
		
		case AVATARGIANTROBOT:
			break;
		
		case AVATARROBOT:
			if (((Robot)bumpedInto).inHittingRange(getCenter())){
				if (ticks == 0){
					lives--;
				}
				if (ticks++ == ticksPerRobotHit)
					ticks = 0;
			}
			
			break;
		
		case DEFAULT:
			break;
		}
		
		if (lives < 0)
			Game.avatarDead();
		
	}

	public void fire(){
		if (weapon == 1){
			fireGrenade();
		}else{
			fireMessile();
		}
	}
	public void changeWeapon(){
		if (weapon == 1)
			weapon = 2;
		else
			weapon = 1;
	}
	
	public void fireGrenade(){
		if (ticks_grenade > 0) return;
		ticks_missile = ticksToAllowGrenade; 

		Grenade c = (Grenade)ObjectFactory.createGameObject(ObjectType.GRENADE);
		c.setPlanet(planet);
		planet.pinpointToPlanet(c);
		c.getPosition().copy(position);
		//c.landOnPlanet(planet);
		c.jump();
	}

	
	public void fireCarrot(){
		Carrot c = (Carrot)ObjectFactory.createGameObject(ObjectType.CARROT);
		c.setPlanet(planet);
		planet.pinpointToPlanet(c);
		c.getPosition().copy(position);
		//c.landOnPlanet(planet);
		c.jump();
	}
	
	
	public void fireMessile(){
		if (ticks_missile > 0) return;
		ticks_missile = ticksToAllowMissile; 
		Missile c = (Missile)ObjectFactory.createGameObject(ObjectType.MISSILE);
		c.setPlanet(planet);
		c.getPosition().copy(position);
		c.fire();
		
	}

	
	

	@Override
	public void clockTicked(ActionEvent arg0) {
		super.clockTicked(arg0);
		ticks_grenade = Math.max(0,ticks_grenade - 1);
		ticks_missile = Math.max(0,ticks_missile - 1);
		
	}

	public void stepForward(){
		walkForward(step);
	}

	public void stepBackward(){
		walkForward(-step);
	}

	public void rotateRight(){
		rotate(rotAngle);
	}
	public void rotateLeft(){
		rotate(-rotAngle);
	}

	public void jump(){
		jump(jumpStrength);
	}

	private void jump(double strength){

		if (this.getMovementControler().inTheAir())
			return;
		this.getMovementControler().addMovement(
				Math3D.scalePoint(getUp(), strength));
		this.getMovementControler().addMovement(
				Math3D.scalePoint(getFace(), strength*4));
	}

	private void walkForward(double distance){
		this.getMovementControler().addMovement(Math3D.scalePoint(getFace(),distance));
	}

	private void rotate(double angle){
		//this.movementControler.rotationY(angle);
		this.getMovementControler().addRotationY(angle);
	}


	public int getCarrotsNum() {
		return carrots;
	}


	public int getLives() {
		return lives;
	}

	public int getWeapon() {
		return weapon;
	}
	

}
